package com.hundsun.ares.studio.emfadapter.editor; import java.util.ArrayList; import java.util.Collection; import java.util.EventObject; import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.common.command.BasicCommandStack; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.CommandStack; import org.eclipse.emf.common.command.CommandStackListener; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.ui.ViewerPane; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EContentAdapter; import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.domain.IEditingDomainProvider; import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; import org.eclipse.emf.edit.provider.ComposedAdapterFactory; import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory; import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory; import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor; import org.eclipse.emf.edit.ui.celleditor.AdapterFactoryTreeEditor; import org.eclipse.emf.edit.ui.dnd.EditingDomainViewerDropAdapter; import org.eclipse.emf.edit.ui.dnd.LocalTransfer; import org.eclipse.emf.edit.ui.dnd.ViewerDragAdapter; import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.emf.edit.ui.provider.UnwrappingSelectionProvider; import org.eclipse.emf.edit.ui.util.EditUIUtil; import org.eclipse.emf.edit.ui.view.ExtendedPropertySheetPage; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.views.contentoutline.ContentOutline; import org.eclipse.ui.views.contentoutline.ContentOutlinePage; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.eclipse.ui.views.properties.IPropertySheetPage; import org.eclipse.ui.views.properties.PropertySheet; import org.eclipse.ui.views.properties.PropertySheetPage; import com.hundsun.ares.studio.core.ARESCore; import com.hundsun.ares.studio.core.ARESModelException; import com.hundsun.ares.studio.core.IARESElement; import com.hundsun.ares.studio.core.IARESResource; import com.hundsun.ares.studio.ui.editor.AbstractHSExtendPointFormEditor; import com.hundsun.ares.studio.ui.editor.AbstractHSFormEditor; import com.hundsun.ares.studio.ui.editor.AbstractHSFormEditorNoUndocontext; import com.hundsun.ares.studio.ui.page.HSComponentbasedFormPage; public abstract class AbstractHSFormEditorEMFAdapterNoUndocontext<T extends EObject> extends AbstractHSFormEditorNoUndocontext<T> implements IEditingDomainProvider, IMenuListener, ISelectionProvider { /** * This keeps track of the editing domain that is used to track all changes to the model. */ protected AdapterFactoryEditingDomain editingDomain; /** * This is the one adapter factory used for providing views of the model. */ protected ComposedAdapterFactory adapterFactory; /** * This keeps track of the active viewer pane, in the book. */ protected ViewerPane currentViewerPane; /** * This is the viewer that shadows the selection in the content outline. * The parent relation must be correctly defined for this to work. */ protected TreeViewer selectionViewer; /** * This listens to which ever viewer is active. */ protected ISelectionChangedListener selectionChangedListener; /** * This keeps track of all the {@link org.eclipse.jface.viewers.ISelectionChangedListener}s that are listening to this editor. */ protected Collection<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>(); /** * This keeps track of the selection of the editor as a whole. */ protected ISelection editorSelection = StructuredSelection.EMPTY; /** * This is the content outline page. */ protected IContentOutlinePage contentOutlinePage; /** * This is the content outline page's viewer. */ protected TreeViewer contentOutlineViewer; /** * This is the property sheet page. */ protected PropertySheetPage propertySheetPage; /** * Դ��ҳҳǩ�� */ protected int sourcePageIndex = -1; protected boolean isRefresh = false; /** * This listens for when the outline becomes active */ protected IPartListener partListener = new IPartListener() { public void partActivated(IWorkbenchPart p) { if (p instanceof ContentOutline) { if (((ContentOutline)p).getCurrentPage() == contentOutlinePage) { getActionBarContributor().setActiveEditor(AbstractHSFormEditorEMFAdapterNoUndocontext.this); // setCurrentViewer(contentOutlineViewer); } } else if (p instanceof PropertySheet) { if (((PropertySheet)p).getCurrentPage() == propertySheetPage) { getActionBarContributor().setActiveEditor(AbstractHSFormEditorEMFAdapterNoUndocontext.this); handleActivate(); } } else if (p == AbstractHSFormEditorEMFAdapterNoUndocontext.this) { handleActivate(); } } public void partBroughtToTop(IWorkbenchPart p) { // Ignore. } public void partClosed(IWorkbenchPart p) { // Ignore. } public void partDeactivated(IWorkbenchPart p) { // Ignore. } public void partOpened(IWorkbenchPart p) { // Ignore. } }; /** * Adapter used to update the problem indication when resources are demanded loaded. */ protected EContentAdapter problemIndicationAdapter = new EContentAdapter() { @Override public void notifyChanged(Notification notification) { handleNotifyChanged(notification); } @Override protected void setTarget(Resource target) { basicSetTarget(target); } @Override protected void unsetTarget(Resource target) { basicUnsetTarget(target); } }; public AbstractHSFormEditorEMFAdapterNoUndocontext() { super(); initializeEditingDomain(); } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { // TODO Auto-generated method stub super.init(site, input); site.setSelectionProvider(this); site.getPage().addPartListener(partListener); } /** * This sets up the editing domain for the model editor. */ protected void initializeEditingDomain() { // Create an adapter factory that yields item providers. // adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE); adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory()); adapterFactory.addAdapterFactory(getResourceItemProviderAdapterFactory()); adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory()); // Create the command stack that will notify this editor as commands are executed. // final BasicCommandStack commandStack = new BasicCommandStack(); // Add a listener to set the most recent command's affected objects to be the selection of the viewer with focus. // commandStack.addCommandStackListener (new CommandStackListener() { public void commandStackChanged(final EventObject event) { getContainer().getDisplay().asyncExec (new Runnable() { public void run() { dirty.setValue(commandStack.isSaveNeeded()); // firePropertyChange(IEditorPart.PROP_DIRTY); // Try to select the affected objects. // Command mostRecentCommand = ((CommandStack)event.getSource()).getMostRecentCommand(); if (mostRecentCommand != null) { for (Object obj : mostRecentCommand.getAffectedObjects()) { if (obj instanceof EObject) { if (!((EObject) obj).eAdapters().contains(problemIndicationAdapter)) { ((EObject) obj).eAdapters().add(problemIndicationAdapter); } } } setSelectionToViewer(mostRecentCommand.getAffectedObjects()); } if (propertySheetPage != null && !propertySheetPage.getControl().isDisposed()) { propertySheetPage.refresh(); } } }); } }); // Create the editing domain with a special command stack. editingDomain = new AdapterFactoryEditingDomain(adapterFactory, commandStack, new HashMap<Resource, Boolean>()); } /** * Handles activation of the editor or it's associated views. */ protected void handleActivate() { // Recompute the read only state. // if (editingDomain.getResourceToReadOnlyMap() != null) { editingDomain.getResourceToReadOnlyMap().clear(); // Refresh any actions that may become enabled or disabled. // setSelection(getSelection()); } } @Override protected void createPages() { createModel(); super.createPages(); if (!getEditingDomain().getResourceSet().getResources().isEmpty()) { createSourcePage(); } // HSResoueceEMFActionBarContributor bar = (HSResoueceEMFActionBarContributor)getActionBarContributor(); // bar.setEditdomain(editingDomain); } /** * This is the method called to load a resource into the editing domain's resource set based on the editor's input. */ public void createModel() { URI resourceURI = EditUIUtil.getURI(getEditorInput()); // try { // // Load the resource through the editing domain. // editingDomain.getResourceSet().getResource(resourceURI, false); // } // catch (Exception e) { // editingDomain.getResourceSet().getResource(resourceURI, false); // } XMLResourceImpl xmlResource = new XMLResourceImpl(resourceURI); xmlResource.getContents().add((EObject) info); editingDomain.getResourceSet().getResources().add(xmlResource); editingDomain.getResourceToReadOnlyMap().put(xmlResource, resource.isReadOnly()); ((EObject)info).eAdapters().add(problemIndicationAdapter); } /** * ��Դ�����仯�� * * @param notification */ protected void handleNotifyChanged(Notification notification) { // do nothing } /** * ����Դ����༭ҳ�� */ protected void createSourcePage() { ViewerPane viewerPane = new ViewerPane(getSite().getPage(), AbstractHSFormEditorEMFAdapterNoUndocontext.this) { @Override public Viewer createViewer(Composite composite) { Tree tree = new Tree(composite, SWT.MULTI); TreeViewer newTreeViewer = new TreeViewer(tree); return newTreeViewer; } @Override protected void createTitleBar() { // TODO Auto-generated method stub } }; viewerPane.createControl(getContainer()); selectionViewer = (TreeViewer)viewerPane.getViewer(); selectionViewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory)); selectionViewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory)); selectionViewer.setInput(editingDomain.getResourceSet().getResources().get(0)); selectionViewer.setSelection(new StructuredSelection(/*editingDomain.getResourceSet().getResources().get(0)*/info), true); selectionViewer.addSelectionChangedListener(new ISelectionChangedListener() { // This just notifies those things that are affected by the section. // public void selectionChanged(SelectionChangedEvent selectionChangedEvent) { setSelection(selectionChangedEvent.getSelection()); } }); // viewerPane.setTitle(editingDomain.getResourceSet()); new AdapterFactoryTreeEditor(selectionViewer.getTree(), adapterFactory); createContextMenuFor(selectionViewer); sourcePageIndex = addPage(viewerPane.getControl()); setPageText(sourcePageIndex, "source"); } /** * This creates a context menu for the viewer and adds a listener as well registering the menu for extension. */ protected void createContextMenuFor(StructuredViewer viewer) { MenuManager contextMenu = new MenuManager("#PopUp"); contextMenu.add(new Separator("additions")); contextMenu.setRemoveAllWhenShown(true); contextMenu.addMenuListener(this); Menu menu= contextMenu.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); getSite().registerContextMenu(contextMenu, new UnwrappingSelectionProvider(viewer)); int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance() }; viewer.addDragSupport(dndOperations, transfers, new ViewerDragAdapter(viewer)); viewer.addDropSupport(dndOperations, transfers, new EditingDomainViewerDropAdapter(editingDomain, viewer)); } public AdapterFactory getAdapterFactory() { return adapterFactory; } public EditingDomain getEditingDomain() { return editingDomain; } /** * ��ȡģ����Դ��Ӧ���������������� * * @return */ protected abstract ComposeableAdapterFactory getResourceItemProviderAdapterFactory(); public void addSelectionChangedListener(ISelectionChangedListener listener) { selectionChangedListeners.add(listener); } public void removeSelectionChangedListener(ISelectionChangedListener listener) { selectionChangedListeners.remove(listener); } public ISelection getSelection() { return editorSelection; } public void setSelection(ISelection selection) { editorSelection = selection; for (ISelectionChangedListener listener : selectionChangedListeners) { listener.selectionChanged(new SelectionChangedEvent(this, selection)); } // setStatusLineManager(selection); } /** * This accesses a cached version of the content outliner. */ public IContentOutlinePage getContentOutlinePage() { if (contentOutlinePage == null) { // The content outline is just a tree. // class MyContentOutlinePage extends ContentOutlinePage { @Override public void createControl(Composite parent) { super.createControl(parent); contentOutlineViewer = getTreeViewer(); contentOutlineViewer.addSelectionChangedListener(this); // Set up the tree viewer. // contentOutlineViewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory)); contentOutlineViewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory)); contentOutlineViewer.setInput(editingDomain.getResourceSet()); // Make sure our popups work. // createContextMenuFor(contentOutlineViewer); if (!editingDomain.getResourceSet().getResources().isEmpty()) { // Select the root object in the view. // contentOutlineViewer.setSelection(new StructuredSelection(editingDomain.getResourceSet().getResources().get(0)), true); } } @Override public void makeContributions(IMenuManager menuManager, IToolBarManager toolBarManager, IStatusLineManager statusLineManager) { super.makeContributions(menuManager, toolBarManager, statusLineManager); // contentOutlineStatusLineManager = statusLineManager; } @Override public void setActionBars(IActionBars actionBars) { super.setActionBars(actionBars); getActionBarContributor().shareGlobalActions(this, actionBars); } } contentOutlinePage = new MyContentOutlinePage(); // Listen to selection so that we can handle it is a special way. // contentOutlinePage.addSelectionChangedListener (new ISelectionChangedListener() { // This ensures that we handle selections correctly. // public void selectionChanged(SelectionChangedEvent event) { handleContentOutlineSelection(event.getSelection()); } }); } return contentOutlinePage; } /** * This accesses a cached version of the property sheet. */ public IPropertySheetPage getPropertySheetPage() { if (propertySheetPage == null) { propertySheetPage = new ExtendedPropertySheetPage(editingDomain) { @Override public void setSelectionToViewer(List<?> selection) { AbstractHSFormEditorEMFAdapterNoUndocontext.this.setSelectionToViewer(selection); AbstractHSFormEditorEMFAdapterNoUndocontext.this.setFocus(); } @Override public void setActionBars(IActionBars actionBars) { super.setActionBars(actionBars); getActionBarContributor().shareGlobalActions(this, actionBars); } }; propertySheetPage.setPropertySourceProvider(new AdapterFactoryContentProvider(adapterFactory)); } return propertySheetPage; } /** * This sets the selection into whichever viewer is active. */ public void setSelectionToViewer(Collection<?> collection) { final Collection<?> theSelection = collection; // Make sure it's okay. // if (theSelection != null && !theSelection.isEmpty()) { // I don't know if this should be run this deferred // because we might have to give the editor a chance to process the viewer update events // and hence to update the views first. // // Runnable runnable = new Runnable() { public void run() { // Try to select the items in the current content viewer of the editor. // if (selectionViewer != null) { selectionViewer.setSelection(new StructuredSelection(theSelection.toArray()), true); } } }; runnable.run(); } } /** * This deals with how we want selection in the outliner to affect the other views. */ public void handleContentOutlineSelection(ISelection selection) { if (selectionViewer != null && !selection.isEmpty() && selection instanceof IStructuredSelection) { Iterator<?> selectedElements = ((IStructuredSelection)selection).iterator(); if (selectedElements.hasNext()) { // Get the first selected element. // Object selectedElement = selectedElements.next(); // If it's the selection viewer, then we want it to select the same selection as this selection. // ArrayList<Object> selectionList = new ArrayList<Object>(); selectionList.add(selectedElement); while (selectedElements.hasNext()) { selectionList.add(selectedElements.next()); } // Set the selection to the widget. // selectionViewer.setSelection(new StructuredSelection(selectionList)); } } } public void menuAboutToShow(IMenuManager manager) { ((IMenuListener)getEditorSite().getActionBarContributor()).menuAboutToShow(manager); } @Override protected void pageChange(int pageIndex) { super.pageChange(pageIndex); // ��Դ��ҳת������ҳ��ʱ��Ҫˢ�£����������ˢ�� if (isRefresh) { Object page = getSelectedPage(); if (page instanceof HSComponentbasedFormPage) { ((HSComponentbasedFormPage) page).refresh(); } } isRefresh = (pageIndex == sourcePageIndex); if (contentOutlinePage != null) { handleContentOutlineSelection(contentOutlinePage.getSelection()); } } @Override public void doSave(IProgressMonitor monitor) { editingDomain.getResourceSet().getResources().clear(); doSaveFile(monitor); if (info.eResource().getURI() == null) { URI uri = EditUIUtil.getURI(getEditorInput()); info.eResource().setURI(uri); } editingDomain.getResourceSet().getResources().add(info.eResource()); selectionViewer.setInput(info.eResource()); //����saveindex����֤undo/redo�������� ((BasicCommandStack)editingDomain.getCommandStack()).saveIsDone(); dirty.setValue(false); } @Override public Object getAdapter(Class key) { if (key.equals(IContentOutlinePage.class)) { return showOutlineView() ? getContentOutlinePage() : null; } else if (key.equals(IPropertySheetPage.class)) { return getPropertySheetPage(); } else { return super.getAdapter(key); } } /** * set focus. */ @Override public void setFocus() { if (currentViewerPane != null) { currentViewerPane.setFocus(); } else { getControl(getActivePage()).setFocus(); } } /** * get editor action bar contributor. */ public EditingDomainActionBarContributor getActionBarContributor() { return (EditingDomainActionBarContributor)getEditorSite().getActionBarContributor(); } /** * Returns whether the outline view should be presented to the user. */ protected boolean showOutlineView() { return true; } @Override public void dispose() { // updateProblemIndication = false; // ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener); getSite().getPage().removePartListener(partListener); adapterFactory.dispose(); if (getActionBarContributor().getActiveEditor() == this) { getActionBarContributor().setActiveEditor(null); } if (propertySheetPage != null) { propertySheetPage.dispose(); } if (contentOutlinePage != null) { contentOutlinePage.dispose(); } super.dispose(); } }